#ifndef _VM_H
#define _VM_H
/**********************************
 * Library to make use of compiler vm 
 *
 * @author Jorge Machado
 * @date 12-12-2008
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "listas.h"

#define OUT_JMP -1;
#define NOTHING_STR = "-"



typedef enum C3argtype_Enum
{
  NOTHING,ID,LITERALINT,LITERALSTRING,LITERALCHAR
} C3argtype;

/**
 * Argument of a ce3 operation
 */

typedef struct C3arg_Struct
{
	C3argtype type;
	int iValue;
	char cValue;
	char* sValue;
	char* idValue;
} C3arg;


/**
 * C3E Operation
 */
typedef enum C3OperationType_Enum
{
   ALLOC,CPY,LEN,LENW,CALL,RETURN,JMP,IFEQ,IFNEQ,IFGT,IFGE,IFLT,IFLE,PUSH,POP,PUSHP,POPP,PLUS,MINUS,TIMES,DIV,REST,IDXR,IDXL,LOCR,LOCL,ADDR,PRINT,PRINTI,READ,PRINTCORE,PRINTIR,PRINTSTACK,PRINTVAR,PRINTMEM,PRINTMEMFREE,PRINTMEMSIZE
} C3OperationType;

typedef struct C3Operation_Struct
{
	int address;
	C3OperationType type;
	C3arg arg1;
	C3arg arg2;
	C3arg arg3;
	
} C3Operation;

typedef struct CodePlaceNode_Struct
{
	List * code;  //list of C3Operation elements
	char * place; //identifier name
}CodePlaceNode;

typedef struct LogicalExpressionNode_Struct
{
	List * trueC3ops;
	List * falseC3ops;	
}LogicalExpressionNode;


char * novaTempGivenStartAndNumber(char start, int counter);
char * novaTemp();
C3Operation * primeiraOperacao(List * operacoes);
C3Operation * segundaOperacao(List * operacoes);
C3Operation * terceiraOperacao(List * operacoes);
C3Operation * ultimaOperacao(List * operacoes);
void printOperation(C3Operation * operation);
void printOperations(List * operations);
void resolve(List * listaOperacoes, int address);
C3arg * novoLiteralInt(int value);
C3arg * novoLiteralChar(char value);
C3arg * novoLiteralString(char * value);
C3arg * novoId(char * id);
C3arg * criaIdTemp();
C3Operation * createOperation(int address, C3OperationType type,C3arg * a1, C3arg * a2, C3arg * a3);
C3arg * getNothingArg();
List * createListWithASingleOperation(C3Operation * op);
List * concatenaCodigo (List * ops1, List * ops2);

#else
/* code to include if the token is defined */
#endif


